package com.diy.sigmund.diycommon.spring.service.impl;

import com.diy.sigmund.diycommon.entity.constant.CommonConstant;
import com.diy.sigmund.diycommon.middleware.cache.redis.RedisService;
import com.diy.sigmund.diycommon.spring.service.ApiIdempotentService;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @author ylm-sigmund
 * @see <a href="https://mp.weixin.qq.com/s?__biz=Mzk0MzIxNTMxNA==&mid=2247486532&idx=2&sn=5efa38393e73caecd3e019584c1fcef0">瞬间几千次的重复提交，我用 SpringBoot+Redis 扛住了！</a>
 * @since 2021/7/29 22:52
 */
@Service
public class ApiIdempotentServiceImpl implements ApiIdempotentService {

    private final Logger log = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private RedisService redisService;

    @Override
    public String createToken() {
        String str = UUID.randomUUID().toString().replace("-", "");
        StringBuilder token = new StringBuilder();
        try {
            token.append(CommonConstant.API_IDEMPOTENT_TOKEN_PREFIX).append(str);
            final String key = token.toString();
            redisService.setXx(key, key, CommonConstant.API_IDEMPOTENT_EXPIRE_TIME, TimeUnit.SECONDS);
            boolean notEmpty = StringUtils.isNotEmpty(key);
            if (notEmpty) {
                return key;
            }
        } catch (Exception e) {
            log.error("createToken error", e);
        }
        return null;
    }

    @Override
    public boolean checkToken(HttpServletRequest request) {
        String token = request.getHeader(CommonConstant.API_IDEMPOTENT_TOKEN);
        if (StringUtils.isBlank(token)) {
            log.error("请求头中token为空");
            return false;
        }
        if (!redisService.exists(token)) {
            log.error("token在缓存中不存在");
            return false;
        }
        boolean remove = redisService.del(token);
        if (!remove) {
            log.error("移除token失败");
            return false;
        }
        return true;
    }
}